use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(default)]
pub struct DbConfig {
    pub host: String,
    pub port: u32,
    pub username: String,
    pub password: String,
    pub database: String,
    pub charset: String,
}

impl DbConfig {
    pub fn new() -> Self {
        Self::default()
    }

    pub fn dsn(&self) -> String {
        format!(
            "{}:{}@tcp({}:{})/{}?charset={}&parseTime=True&loc=Local",
            self.username, self.password, self.host, self.port, self.database, self.charset
        )
    }
}

impl Default for DbConfig {
    fn default() -> Self {
        Self {
            host: "127.0.0.1".to_owned(),
            port: 3306,
            username: "root".to_owned(),
            password: "root".to_owned(),
            database: "ews".to_owned(),
            charset: "utf8mb4".to_owned(),
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_default() {
        let conf = DbConfig::default();

        assert_eq!(conf.host, "127.0.0.1");
        assert_eq!(conf.port, 3306);
        assert_eq!(conf.username, "root");
        assert_eq!(conf.password, "root");
        assert_eq!(conf.database, "ews");
        assert_eq!(conf.charset, "utf8mb4");
    }
    #[test]
    fn test_dsn() {
        let conf = DbConfig::default();

        assert_eq!(
            conf.dsn(),
            "root:root@tcp(127.0.0.1:3306)/ews?charset=utf8mb4&parseTime=True&loc=Local"
        );
    }
}
